<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>JSDoc: Source: utils.js</title>

    <script src="scripts/prettify/prettify.js"> </script>
    <script src="scripts/prettify/lang-css.js"> </script>
    <!--[if lt IE 9]>
      <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
    <![endif]-->
    <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
    <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
</head>

<body>

<div id="main">

    <h1 class="page-title">Source: utils.js</h1>

    



    
    <section>
        <article>
            <pre class="prettyprint source linenums"><code>/**
 * ChiVoxSDK内部经常使用的公用方法封装。
 *
 * @namespace Utils
 * @author Don Li &lt;kai.li@chivox.com>
 * @licence
 * Copyright (c) 2017 - 2020 ChiVox Inc. All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

class Utils {
    /**
     * 从default_properties来扩展new_properties的属性。new_properties中不存在的属性或key，会从default_properties里取默认值。&lt;br/>
     * 如果allow_other设置成true，允许使用default_properties字典里没有的属性。
     *
     * @function Utils.extend
     *
     * @param {Object} new_properties - 要扩展的字典。
     * @param {Object} default_properties- 默认字典，用于扩展new_properties变量中没有设置的属性。
     * @param {boolean=} allow_other - 是否允许new_properties字典里存在default_properties没有的属性。默认: false
     * @return  {Object} - 扩展后的字典。
     */
    static extend(new_properties, default_properties, allow_other = false) {
        if (!allow_other) {
            for (var prop in new_properties) {
                if (!default_properties.hasOwnProperty(prop)) {
                    console.error(`[ Utils.extend ] can not assign prop: ${prop}. not allowed by default value.`, new_properties, default_properties);
                    return default_properties;
                }
            }
        }

        new_properties = Object.assign({}, default_properties, new_properties);

        return new_properties;
    }

    /**
     * 判断当前浏览器是否支持HTML5模式。&lt;br/>
     * 如果在初始化ChiVoxSDK的时候没有指定mode参数，会自动根据这个函数返回值来决定是否自动使用HTML5模式。
     *
     * @function Utils.support_h5
     * @return  {boolean} - 当前浏览器是否支持HTML5模式。
     */
    static support_h5() {
        let supported = false;
        navigator.getUserMedia = (navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia);

        if (!navigator.getUserMedia) {
            console.error('[ Utils.support_h5 ] Your Browser does not support navigator.getUserMedia.');
        } else if (!window.WebSocket) {
            console.error('[ Utils.support_h5 ] Your Browser does not support window.WebSocket.');
        } else if (document.location.protocol !== 'https:') {
            console.error(`[ Utils.support_h5 ] The current address: ${document.location.href}, it not based on HTTPS.`);
        } else if (!window.Worker) {
            console.error('[ Utils.support_h5 ] Your Browser does not support window.Worker.');
        } else if (!navigator.getUserMedia) {
            console.error(`[ Utils.support_h5 ] Your Browser does not support getUserMedia. current: ${navigator.getUserMedia}`);
        } else {
            supported = true;
        }

        return supported;
    }

    /**
     * 使用AJAX发起一个异步HTTP请求，支持GET和POST两种方式， 返回一个Promise。&lt;br/>
     *
     * @function Utils.ajax
     *
     * @param {Object} options - 根据options发起本次HTTP请求。默认的options属性如下：
     * @param {string=} options.type - HTTP请求的类型。允许的值有：'GET', 'POST', 默认：'GET'
     * @param {string} options.url - HTTP请求的地址。
     * @param {string=} options.querystring - HTTP请求的参数。格式：a=1&amp;b=2
     * @param {boolean=} options.async - 是否使用XMLHttpRequest的async模式。默认：true
     * @param {string=} options.dataType - 返回值的数据类型。默认空，可以设置为'json'，返回结果会自动转换为JSON格式。
     * @return  {Object} - 返回HTTP请求的Promise。
     *
     * @example
     * // 发起http请求：
     * Utils.ajax({url: '/xxx', dataType: 'json'}).then((json) => { xx; }).catch((err) => { print err; });
     */
    static ajax(options) {
        let xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP');

        let opt = {
            type: options.type || 'GET',
            url: options.url || '',
            async: options.async || true,
            dataType: options.dataType || '',
            querystring: options.querystring || ''
        };

        return new Promise((resolve, reject) =>{
            xhr.open(opt.type, opt.url, opt.async);
            xhr.onreadystatechange = () => {
                if (xhr.readyState === 4) {
                    if (xhr.status === 200) {
                        const data = (opt.dataType === 'json') ? JSON.parse(xhr.responseText) : xhr.responseText;
                        resolve(data);
                    } else {
                        reject(new Error(xhr.status || 'Server is failed.'));
                    }
                }
            };

            xhr.onerror = () => {
                reject(new Error(xhr.status || 'Server is failed.'));
            };

            xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
            xhr.send(opt.querystring);
        });
    }

    /**
     * 根据当前环境， 返回一个合适的Buffer Size，HTML5模式的录音机在边录边评时使用。&lt;br/>
     *
     * @function Utils.buff_size
     * @return  {int} - 返回当前环境合适的buffer size。
     */
    static buff_size() {
        if (/(Win(dows )?NT 6\.2)/.test(navigator.userAgent)) {
            return 1024;  //Windows 8
        } else if (/(Win(dows )?NT 6\.1)/.test(navigator.userAgent)) {
            return 1024;  //Windows 7
        } else if (/(Win(dows )?NT 6\.0)/.test(navigator.userAgent)) {
            return 2048;  //Windows Vista
        } else if (/Win(dows )?(NT 5\.1|XP)/.test(navigator.userAgent)) {
            return 4096;  //Windows XP
        } else if (/Mac|PPC/.test(navigator.userAgent)) {
            return 1024;  //Mac OS X
        } else if (/Linux/.test(navigator.userAgent)) {
            return 8192;  //Linux
        } else if (/iPhone|iPad|iPod/.test(navigator.userAgent)) {
            return 2048;  //iOS
        } else {
            return 16384; //Otherwise
        }
    }

    /**
     * 对elements数组内所有的element绑定evname事件函数为func。&lt;br/>
     *
     * @function Utils.bind_mul
     *
     * @param {Array} elements - 准备绑定事件的HTML DOM节点数组。
     * @param {string} evname - 要绑定的事件名称。如：'click'
     * @param {callback} func - 事件触发的函数。
     */
    static bind_mul(elements, evname, func) {
        for (var i = 0; i &lt; elements.length; i++)
            Utils.bind(elements[i], evname, func);
    }


    /**
     * 对ele绑定evname事件函数为func。&lt;br/>
     *
     * @function Utils.bind
     *
     * @param {Object} ele - 准备绑定事件的HTML DOM节点。
     * @param {string} evname - 要绑定的事件名称。如：'click'
     * @param {callback} func - 事件触发的函数。
     */
    static bind(ele, evname, func) {
        if (ele.addEventListener) {
            ele.addEventListener(evname, func);
        } else {
            ele.attachEvent('on' + evname, () => { func.call(ele); });
        }
    }

    /**
     * 对ele解除绑定了evname的事件函数func。&lt;br/>
     *
     * @function Utils.unbind
     *
     * @param {Object} ele - 要解除绑定事件的HTML DOM节点。
     * @param {string} evname - 要解除绑定的事件名称。如：'click'
     * @param {callback} func - 事件触发的函数。
     */
    static unbind(ele, evname, func) {
        if (ele.removeEventListener) {
            ele.removeEventListener(evname, func);
        } else {
            ele.detachEvent('on' + evname, func);
        }
    }

    /**
     * 为ele增加CSS类。&lt;br/>
     *
     * @function Utils.addClass
     *
     * @param {Object} ele - HTML DOM节点。
     * @param {string} classname - 要增加的CSS类名称。
     */
    static addClass(ele, classname) {
        if (ele) {
            if (ele.classList)
                ele.classList.add(classname);
            else
                ele.className += ' ' + classname;
        } else {
            console.warn('ele is null');
        }
    }

    /**
     * 移除ele的CSS类。&lt;br/>
     *
     * @function Utils.removeClass
     *
     * @param {Object} ele - HTML DOM节点。
     * @param {string} classname - 要移除的CSS类名称。
     */
    static removeClass(ele, classname) {
        if (ele) {
            if (ele.classList)
                ele.classList.remove(classname);
            else
                ele.className = ele.className.replace(new RegExp('(^|\\b)' + className.split(' ').join('|') + '(\\b|$)', 'gi'), ' ');
        } else {
            console.warn('ele is null');
        }
    }

    /**
     * 判断ele是否存在CSS类。&lt;br/>
     *
     * @function Utils.hasClass
     *
     * @param {Object} ele - HTML DOM节点。
     * @param {string} classname - 要移除的CSS类名称。
     * @return {boolean} - ele是否存在classname的CSS类。
     */
    static hasClass(ele, classname) {
        if (ele.classList)
            return ele.classList.contains(classname);
        else
            return new RegExp('(^| )' + classname + '( |$)', 'gi').test(ele.classname);
    }

    /**
     * 在root节点下根据selector，递归查找所有被选中的子节点。&lt;br/>
     *
     * @function Utils.find_all
     *
     * @param {string} selector - 一个由逗号连接的包含一个或多个CSS选择器的字符串。
     * @return {Array} - 所有符合条件的子DOM节点列表。
     */
    static find_all(root, selector) {
        if (root.querySelectorAll)
            return root.querySelectorAll(selector);
    }

    /**
     * 在root节点下根据selector，递归查找第一个被选中的子节点。&lt;br/>
     *
     * @function Utils.find
     *
     * @param {string} selector - 一个由逗号连接的包含一个或多个CSS选择器的字符串。
     * @return {Object} - 符合条件的第一个子DOM节点。
     */
    static find(root, selector) {
        var all = Utils.find_all(root, selector);

        if (all &amp;&amp; all.length > 0)
            return all[0];
        else
            console.debug(`not found element. selector: ${selector}`);
    }

    /**
     * 计算HTML DOM节点的宽度。&lt;br/>
     *
     * @function Utils.width
     *
     * @param {Object} element - HTML DOM节点。
     * @return {int} - DOM节点的宽度。
     */
    static width(element) {
        if (element.currentStyle)
            return element.currentStyle.width;
        else
            return getComputedStyle(element, false).width;
    }

    /**
     * 生成一个UUID字符串。&lt;br/>
     *
     * @function Utils.uuid
     * @return {string} - UUID字符串。
     */
    static uuid() {
        return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g,
                (c) => {
                    let r = Math.random()*16|0, v = c == 'x' ? r : (r&amp;0x3|0x8);
                    return v.toString(16);
                }
                );
    }

    /**
     * 判断item是否存在于arr数组中。&lt;br/>
     *
     * @function Utils.in_array
     * @param {Object} item - 要判断的字符串。如果item存在于arr，返回true。
     * @param {Array} arr - 要判断的数组。
     * @return {boolean} - 是否存在。
     */
    static in_array(item, arr) {
        for (var i = 0; i &lt; arr.length; i++) {
            if (item == arr[i]) return true;
        }

        return false;
    }
}

export default Utils
</code></pre>
        </article>
    </section>




</div>

<nav>
    <h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-ChiVoxSDK.html">ChiVoxSDK</a></li><li><a href="module-ChiVoxSDK_flash.html">ChiVoxSDK/flash</a></li><li><a href="module-ChiVoxSDK_html5.html">ChiVoxSDK/html5</a></li><li><a href="module-ChiVoxSDK_lib.html">ChiVoxSDK/lib</a></li><li><a href="module-ChiVoxSDK_Paragraph.html">ChiVoxSDK/Paragraph</a></li><li><a href="module-ChiVoxSDK_score.html">ChiVoxSDK/score</a></li></ul><h3>Classes</h3><ul><li><a href="module-ChiVoxSDK_flash.FlashPlayer.html">FlashPlayer</a></li><li><a href="module-ChiVoxSDK_flash.FlashRecorder.html">FlashRecorder</a></li><li><a href="module-ChiVoxSDK_html5.Html5Player.html">Html5Player</a></li><li><a href="module-ChiVoxSDK_html5.Html5Recorder.html">Html5Recorder</a></li><li><a href="module-ChiVoxSDK_html5-VolumeBar.html">VolumeBar</a></li><li><a href="module-ChiVoxSDK_lib-EnScoreMap.html">EnScoreMap</a></li><li><a href="module-ChiVoxSDK_lib-StatusCode.html">StatusCode</a></li><li><a href="module-ChiVoxSDK_Paragraph-Paragraph.html">Paragraph</a></li><li><a href="module-ChiVoxSDK_score-Char.html">Char</a></li><li><a href="module-ChiVoxSDK_score-CnSentScore.html">CnSentScore</a></li><li><a href="module-ChiVoxSDK_score-CnWordScore.html">CnWordScore</a></li><li><a href="module-ChiVoxSDK_score-EnSentRec.html">EnSentRec</a></li><li><a href="module-ChiVoxSDK_score-EnSentScore.html">EnSentScore</a></li><li><a href="module-ChiVoxSDK_score-EnWordScore.html">EnWordScore</a></li><li><a href="module-ChiVoxSDK_score-Phone.html">Phone</a></li><li><a href="module-ChiVoxSDK_score-Word.html">Word</a></li><li><a href="module-ChiVoxSDK-ChiVoxSDK.html">ChiVoxSDK</a></li><li><a href="module-ChiVoxSDK-ControlPanel.html">ControlPanel</a></li><li><a href="module-ChiVoxSDK-Dialog.html">Dialog</a></li><li><a href="module-ChiVoxSDK-PlayerBuilder.html">PlayerBuilder</a></li><li><a href="module-ChiVoxSDK-ProgressBar.html">ProgressBar</a></li><li><a href="module-ChiVoxSDK-RecorderBuilder.html">RecorderBuilder</a></li></ul><h3>Namespaces</h3><ul><li><a href="public.html">public</a></li><li><a href="Utils.html">Utils</a></li></ul><h3>Global</h3><ul><li><a href="global.html#Default_ChiVoxPlayer_Options">Default_ChiVoxPlayer_Options</a></li><li><a href="global.html#Default_ChiVoxRecorder_Options">Default_ChiVoxRecorder_Options</a></li><li><a href="global.html#Default_ChiVoxSDK_Options">Default_ChiVoxSDK_Options</a></li><li><a href="global.html#Default_Paragraph_Options">Default_Paragraph_Options</a></li><li><a href="global.html#get_sig">get_sig</a></li><li><a href="global.html#tts">tts</a></li></ul>
</nav>

<br class="clear">

<footer>
    Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Thu Sep 21 2017 16:38:41 GMT+0800 (CST)
</footer>

<script> prettyPrint(); </script>
<script src="scripts/linenumber.js"> </script>
</body>
</html>
